/*
 * $Id: sysapi_opentmp.c,v 1.7 2006-11-29 03:55:11 bacon Exp $
 */

#include <xp/bas/sysapi.h>
#include <xp/bas/string.h>
#include <xp/bas/time.h>
#include <xp/bas/errno.h>

#define __TMP_MAX 16384

xp_hnd_t xp_opentmp (xp_char_t* tmpl)
{
	xp_size_t len, count;
#ifdef XP_HAVE_UINT64_T
	xp_uint64_t value = 0;
#else
	xp_uint32_t value = 0;
#endif
	xp_char_t* xx;
	/*xp_timeval_t tv;*/
	xp_time_t tv;


	static const xp_char_t __letters[] = {
		XP_CHAR('a'), XP_CHAR('b'), XP_CHAR('c'),
		XP_CHAR('d'), XP_CHAR('e'), XP_CHAR('f'),
		XP_CHAR('g'), XP_CHAR('h'), XP_CHAR('i'),
		XP_CHAR('j'), XP_CHAR('k'), XP_CHAR('l'),
		XP_CHAR('m'), XP_CHAR('n'), XP_CHAR('o'),
		XP_CHAR('p'), XP_CHAR('q'), XP_CHAR('r'),
		XP_CHAR('s'), XP_CHAR('t'), XP_CHAR('u'),
		XP_CHAR('v'), XP_CHAR('w'), XP_CHAR('x'),
		XP_CHAR('y'), XP_CHAR('z'),

		XP_CHAR('A'), XP_CHAR('B'), XP_CHAR('C'),
		XP_CHAR('D'), XP_CHAR('E'), XP_CHAR('F'),
		XP_CHAR('G'), XP_CHAR('H'), XP_CHAR('I'),
		XP_CHAR('J'), XP_CHAR('K'), XP_CHAR('L'),
		XP_CHAR('M'), XP_CHAR('N'), XP_CHAR('O'),
		XP_CHAR('P'), XP_CHAR('Q'), XP_CHAR('R'),
		XP_CHAR('S'), XP_CHAR('T'), XP_CHAR('U'),
		XP_CHAR('V'), XP_CHAR('W'), XP_CHAR('X'),
		XP_CHAR('Y'), XP_CHAR('Z'),

		XP_CHAR('0'), XP_CHAR('1'), XP_CHAR('2'),
		XP_CHAR('3'), XP_CHAR('4'), XP_CHAR('5'),
		XP_CHAR('6'), XP_CHAR('7'), XP_CHAR('8'),
		XP_CHAR('9')
	};

	len = xp_strlen(tmpl);

	if (len < 6 || xp_strcmp(&tmpl[len - 6], XP_TEXT("XXXXXX")) != 0) {
		xp_seterrno (XP_EINVAL);
		return XP_HND_INVALID;
	}

	xx = &tmpl[len - 6];

	/*
	if (gettimeofday(&tv, XP_NULL) == -1) return XP_HND_INVALID;
	value += ((xp_uint64_t)tv.tv_usec << 16) ^ tv.tv_sec ^ xp_getpid();
	*/
	if (xp_gettime(&tv) == -1) return XP_HND_INVALID;
	value += tv ^ xp_getpid ();

	for (count = 0; count < __TMP_MAX; count++) {
		xp_hnd_t handle;
	#ifdef XP_HAVE_UINT64_T
		xp_uint64_t v = value;
	#else
		xp_uint32_t v = value;
	#endif

		xx[0] = __letters[v % xp_countof(__letters)]; 
		v /= xp_countof(__letters);

		xx[1] = __letters[v % xp_countof(__letters)]; 
		v /= xp_countof(__letters);

		xx[2] = __letters[v % xp_countof(__letters)]; 
		v /= xp_countof(__letters);

		xx[3] = __letters[v % xp_countof(__letters)]; 
		v /= xp_countof(__letters);

		xx[4] = __letters[v % xp_countof(__letters)]; 
		v /= xp_countof(__letters);

		xx[5] = __letters[v % xp_countof(__letters)]; 
		v /= xp_countof(__letters);

		handle = xp_open (tmpl, 
			XP_OPEN_READ | XP_OPEN_WRITE | 
			XP_OPEN_CREATE | XP_OPEN_EXCLUSIVE, 0600);
		if (handle != XP_HND_INVALID) return handle;

		value += 7777;
	}

	tmpl[0] = XP_CHAR('\0');
	xp_seterrno (XP_EBUSY);
	return XP_HND_INVALID;
}
